using System;
using System.Reflection;
using Microsoft.SmallBasic.Library;

namespace SmallBasicFun.Quizes
{
    public class Question
    {
        private readonly object MainObject;
        public readonly string MethodName;
        private readonly Type ObjectType;

        public Question(Type objectType, object mainObject, string methodName)
        {
            ObjectType = objectType;
            MainObject = mainObject;
            MethodName = methodName;
            Result = false;
        }

        public bool Result { get; set; }

        public void RunWithFailure()
        {
            RunMethod(() => { throw new ArgumentException("Unknow Method " + MethodName); });
        }

        private void RunMethod(Action fail)
        {
            try
            {
                MethodInfo method = ObjectType.GetMethod(MethodName, BindingFlags.NonPublic | BindingFlags.Static);
                if (method != null)
                {
                    method.Invoke(MainObject, null);
                }
                else
                {
                    fail();
                }
            }
            catch (TargetInvocationException e)
            {
                throw e.GetBaseException();
            }
        }

        public void Run()
        {
            RunMethod(() => { });
        }

        public Primitive GetVariable(string name)
        {
            FieldInfo member = ObjectType.GetField(name, BindingFlags.NonPublic | BindingFlags.Static);
            if (member != null)
            {
                return (Primitive) member.GetValue(null);
            }
            return null;
        }

        public void SetVariable(string name, Primitive value)
        {
            FieldInfo member = ObjectType.GetField(name, BindingFlags.NonPublic | BindingFlags.Static);
            if (member != null)
            {
                member.SetValue(null, value);
            }
        }
    }
}